package club.hicode.daydayup.zookeeper;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.junit.Test;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 分布式锁的
 *
 * @author LiuChunfu
 * @date 2018/6/4
 */
public class DistrubutedLock {

    private static final String CONNECT_STR = "192.168.100.152:2181";

    private static final String LOCK_PATH = "/lock/app1-";

    @Test
    public void testTempSequene() throws Exception {

        CuratorFramework client = CuratorFrameworkFactory.newClient(CONNECT_STR, new ExponentialBackoffRetry(1000, 3));
        client.start();
        //创建临时节点的办法如下所示：其实前面部分只是头，后续会在后面自动拼接
        String s = client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(LOCK_PATH);
        System.out.println(s);
        ThreadUtil.sleep(5, TimeUnit.HOURS);
    }

    @Test
    public void testListener() throws Exception {

        CuratorFramework client = CuratorFrameworkFactory.newClient(CONNECT_STR, new ExponentialBackoffRetry(1000, 3));
        client.start();
        List<String> list = client.getChildren().forPath("/lock");
        Optional<String> min = list.stream().min((t1, t2) -> {
            String s1 = StrUtil.removePrefix(t1, "app1-");
            Integer i1 = Convert.toInt(s1);
            String s2 = StrUtil.removePrefix(t2, "app1-");
            Integer i2 = Convert.toInt(s2);
            return i1 - i2;
        });

        Optional<String> min1 = list.stream().min(String::compareTo);
        System.out.println(min1.get());
        System.out.println(min.get());
    }

    @Test
    public void createListener() throws Exception {
        CuratorFramework client = CuratorFrameworkFactory.newClient(CONNECT_STR, new ExponentialBackoffRetry(1000, 3));
        client.start();
        client.getData().usingWatcher(new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                if (event.getType() == Event.EventType.NodeDeleted) {
                    System.out.println("你获得了suo锁。。。");
                    return;
                }
            }
        }).forPath("/lock/app1-0000000001");

        ThreadUtil.sleep(5, TimeUnit.HOURS);
    }
    //
    //@Test
    //public void lockTest1() {
    //    InterProcessMutex lock = new InterProcessMutex(this.client, "/"+uniqueLockId);
    //}

    @Test
    public void testDistLock() throws Exception {
        DistLock distLock = new DistLock();
        boolean ff = distLock.lock("ff", "123");
        boolean ff2 = distLock.lock("ff", "123");

        System.out.println(ff);
        System.out.println(ff2);

    }
}
